package com.af.security.mgt.account.register.log;

import com.af.security.mgt.account.register.dto.UserDto;
import com.af.security.mgt.account.register.token.UserRegisterToken;
import com.af.security.mgt.account.register.token.UserRegisterTokenService;
import com.af.security.mgt.user.User;
import com.af.security.mgt.user.UserService;
import com.github.yitter.idgen.YitIdHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;

import java.util.Iterator;
import java.util.List;

/**
 * @author : zhenyun.su
 * @since : 2019/6/25
 */

@Service
public class UserRegisterLogService {
    private static final Logger logger = LoggerFactory.getLogger(UserRegisterLogService.class);
    @Autowired
    private UserService userService;
    @Autowired
    private UserRegisterTokenService userRegisterTokenService;
    @Autowired
    private UserRegisterFailureRepository userRegisterFailureRepository;
    @Autowired
    private UserRegisterLogRepository userRegisterLogRepository;


    public void validationUser(UserDto userDto, BindingResult result) {
        if (StringUtils.isEmpty(userDto.getUsername())) {
            result.rejectValue("username", "message.userName");
        }
        if (StringUtils.isEmpty(userDto.getPassword())) {
            result.rejectValue("password", "message.passWord");
        }
        if (!userDto.getPassword().equals(userDto.getConfirmPass())) {
            result.rejectValue("matchingPassword", "message.password.notMatch");
        }
        if (userService.existsByUsername(userDto.getEmail())) {
            result.rejectValue("email", "message.regError");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public UserRegisterFailure saveFailure(UserRegisterFailure userRegisterFailure) {
        if (userRegisterFailure.getId() != null){
            userRegisterFailure.setId(YitIdHelper.nextId());
        }
        return userRegisterFailureRepository.save(userRegisterFailure);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteFailure(UserRegisterFailure userRegisterFailure) {
        userRegisterFailureRepository.delete(userRegisterFailure);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void saveLog(UserRegisterLog log) {
        try {
            if (log.getId() != null){
                log.setId(YitIdHelper.nextId());
            }
            if (log.getStatus()) {
                userRegisterLogRepository.save(log);
            } else {
                UserRegisterFailure queue = new UserRegisterFailure();
                queue.setStatus(false);
                queue.setLastMsg(log.getLastMsg());
                queue.setUserId(log.getUserId());
                queue.setSubject(log.getSubject());
                queue.setText(log.getText());
                queue.setToken(log.getToken());
                queue.setCreatedDate(log.getCreatedDate());
                queue.setSendDate(log.getSendDate());
                userRegisterFailureRepository.save(queue);
            }
        } catch (Exception e) {
            logger.error("save, exception: {}", e.getMessage());
            //nothing
        }
    }

    /**
     * @comment : 调度任务 - 处理注册确认失败
     */
    public void batchDoingRegisterFailure() {
        List<UserRegisterFailure> queues = userRegisterFailureRepository.findByStatus(false);
        if (queues != null) {
            Iterator<UserRegisterFailure> iterators = queues.iterator();
            while (iterators.hasNext()) {
                doingRegisterFailure(iterators.next());
            }
        }
    }
    @Transactional(rollbackFor = Exception.class)
    public void doingRegisterFailure(UserRegisterFailure queue) {
        UserRegisterLog registerLog = UserRegisterLog.of(queue.getUserId(), queue.getSubject(), queue.getText());
        try {
            User user = userService.getById(queue.getUserId());
            if (user == null) {
                registerLog.setLastMsg("user not exist");
            } else {
                String token = userRegisterTokenService.sendTokenMail(user, queue.getSubject(), queue.getText());
                registerLog.setToken(token);
                registerLog.setStatus(true);
                registerLog.setLastMsg("success");
            }
        } catch (Exception e) {
            String error = e.getMessage();
            registerLog.setStatus(false);
            registerLog.setLastMsg(error);
        } finally {
            userRegisterFailureRepository.delete(queue);
            userRegisterLogRepository.save(registerLog);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public User saveUser(User user) {
        return userService.save(user);
    }

    /**
     * @comment : 激活用户并注册token失效
     */
    @Transactional(rollbackFor = Exception.class)
    public void activateUser(UserRegisterToken token) {
        User user = userService.getById(token.getUserId());
        user.setEnabled(true);
        userService.save(user);
        userRegisterTokenService.tokenDisable(token);
    }


    public UserRegisterToken findByToken(String token) {
        return userRegisterTokenService.findByToken(token);
    }

}
